﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Data.OleDb;

namespace LayoutEdit
{
    public partial class Form1 : Form
    {
        LayoutFile layout = new LayoutFile();
        Dial Percentage = new Dial();
        Dial Fill = new Dial();
        public Form1()
        {
            InitializeComponent();
        }

        private void btnLoad_Click(object sender, EventArgs e)
        {
            if (od.ShowDialog(this) == DialogResult.Cancel) return;
            layout.FileName = od.FileName;
            dg.Columns["ItemName"].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
            this.Text = "Layout Editor: " + layout.FileName + " - " + layout.HouseType + ": " + layout.HouseID;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            dg.DataSource = layout.HouseItems;                      
            dg.Columns["x"].HeaderText = "+ West / - East";
            dg.Columns["y"].HeaderText = "+ South / - North";
            dg.Columns["z"].HeaderText = "+ Up / - Down";
            dg.Columns["Rotation"].HeaderText = "Z Rotation";
            dg.Columns["Pitch"].HeaderText = "X Rotation";
            dg.Columns["Roll"].HeaderText = "Y Rotation";

            dg.Columns["x"].DefaultCellStyle.Format = "0.00000000";
            dg.Columns["y"].DefaultCellStyle.Format = "0.00000000";
            dg.Columns["z"].DefaultCellStyle.Format = "0.00000000";
            dg.Columns["Rotation"].DefaultCellStyle.Format = "0.00000000";
            dg.Columns["Pitch"].DefaultCellStyle.Format = "0.00000000";
            dg.Columns["Roll"].DefaultCellStyle.Format = "0.00000000";
            dg.Columns["Scale"].DefaultCellStyle.Format = "0.00000000";

            this.Text = "Layout Editor: No File Loaded";

            Percentage.Top = lbl_off.Bottom; ;
            Percentage.Left = lbl_off.Left; ;
            Percentage.Width = 50;
            Percentage.Height = 50;
            Percentage.BackColor = tabPage1.BackColor;
            Percentage.Wrap = true;
            Percentage.ValueChanged += new EventHandler(Percentage_ValueChanged);
            tabPage1.Controls.Add(Percentage);

            Fill.Top = lbl_Fill.Bottom;
            Fill.Left = lbl_Fill.Left;
            Fill.Width = 50;
            Fill.Height = 50;
            Fill.BackColor = tabPage1.BackColor;
            Fill.Wrap = false;
            Fill.StartingOffset = 270;
            Fill.FillMode = Dial.FillType.Pie;
            Fill.ValueChanged += new EventHandler(Fill_ValueChanged);
            Fill.Value = 359;
            tabPage1.Controls.Add(Fill);
        }

        void Fill_ValueChanged(object sender, EventArgs e)
        {
            double FillValue = (Fill.Value == 0) ? 0 : (((double)Fill.Value + 1) / (double)360);
            lbl_Fill.Text = "Fill: " + String.Format("{0:0.0%}", FillValue);
        }

        void Percentage_ValueChanged(object sender, EventArgs e)
        {
            lbl_off.Text = "Start Offset:" + Environment.NewLine + Percentage.Value.ToString();
        }

        private void txtSearch_TextChanged(object sender, EventArgs e)
        {
            if (txtSearch.Text.Trim().Length != 0)
            {
                string[] Search = txtSearch.Text.Trim().Split(' ');
                string Filter = string.Empty;
                int tick = 0;
                foreach (string Param in Search)
                {
                    if (tick > 0) Filter += "AND ";
                    Filter += string.Format("ItemName Like '%{0}%' ", Param.Replace("'","''"));
                    tick++;
                }
                layout.HouseItems.DefaultView.RowFilter = Filter;
            }
            else
            {
                layout.HouseItems.DefaultView.RowFilter = "";
            }
        }

        private void lblClearSearch_Click(object sender, EventArgs e)
        {
            txtSearch.Clear();
        }

        private void mnuSaveAs_Click(object sender, EventArgs e)
        {
            sd.FileName = layout.FileName;
            if (sd.ShowDialog(this) != DialogResult.Cancel)
            {
                layout.SaveFile(sd.FileName);
                this.Text = "Layout Editor: " + layout.FileName + " - " + layout.HouseType + ": " + layout.HouseID;
            }
        }

        private void mnuSave_Click(object sender, EventArgs e)
        {
            layout.SaveFile();
        }

        private void mnuEffectCircle_Click(object sender, EventArgs e)
        {
            Placement.HouseItem[] Items = SelectedGridToItems();
            Placement.Vector3D CenterPoint = new Placement.Vector3D(
                double.Parse(txtCirCentX.Text)
                , double.Parse(txtCirCentY.Text)
                , double.Parse(txtCirCentZ.Text));
            int StartingPoint = Percentage.Value;
            double FillPerc = (double)Fill.Value / 359d;
            double Radius = double.Parse(txtRadius.Text);
            Placement.DirectionType Reverse = (chkReverse.Checked) ? Placement.DirectionType.Reverse : Placement.DirectionType.Forward;
            int Orientation = (chkVertical.Checked) ? 1 : 0;
            int Facing = (chkEastWest.Checked) ? 1 : 0;
            bool sVertical = rdo_From_Ground.Checked ;
            bool Spiral = chkSpiral.Checked;
            Items = Placement.CirclePlane(Items, CenterPoint, Orientation, Radius, Facing, double.Parse(txtEndZ.Text),
                Reverse, FillPerc, chkRotate.Checked, StartingPoint, chk90Offset.Checked, Spiral, sVertical, double.Parse(txtRevolutions.Text), chkPointTops.Checked);
            layout.ItemstoDB(Items);
        }
       
        private Placement.HouseItem[] SelectedGridToItems()
        {
            Placement.HouseItem[] Items = new Placement.HouseItem[dg.SelectedRows.Count];
            int i = 0;
            foreach (DataGridViewRow row in dg.SelectedRows)
            {
                Items[i].ID = int.Parse(row.Cells["ID"].Value.ToString());
                Items[i].DatabaseID = int.Parse(row.Cells["DatabaseID"].Value.ToString());
                Items[i].InCrate = bool.Parse(row.Cells["InCrate"].Value.ToString());
                Items[i].ItemID = Int64.Parse(row.Cells["ItemID"].Value.ToString());
                Items[i].ItemName = row.Cells["ItemName"].Value.ToString();
                Items[i].Pitch = decimal.Parse(row.Cells["Pitch"].Value.ToString());
                Items[i].Roll = decimal.Parse(row.Cells["Roll"].Value.ToString());
                Items[i].Rotation = decimal.Parse(row.Cells["Rotation"].Value.ToString());
                Items[i].Scale = decimal.Parse(row.Cells["Scale"].Value.ToString());
                Items[i].x = decimal.Parse(row.Cells["x"].Value.ToString());
                Items[i].y = decimal.Parse(row.Cells["y"].Value.ToString());
                Items[i].z = decimal.Parse(row.Cells["z"].Value.ToString());
                i++;
            }
            return Items;
        }
       
        private void button2_Click(object sender, EventArgs e)
        {
            int ItemsCount = dg.SelectedRows.Count;
            if (ItemsCount == 0) { MessageBox.Show("No rows selected. Aborting."); return; }
            Placement.Vector3D v3 = new Placement.Vector3D(double.Parse(txtStartX.Text), double.Parse(txtStartY.Text), double.Parse(txtStartZ.Text));
            int Rows = int.Parse(txtRows.Text);
            int Columns = int.Parse(txtColumns.Text);
            decimal Spacing = decimal.Parse(txtSpacing.Text);
            decimal Scaling = decimal.Parse(txtScaling.Text);
            int RC = Rows * Columns;
            if (RC == 0)
            {
                MessageBox.Show("You need to have at least 1 column and 1 row. Aborting.");
                return;
            }
            if (RC == 1)
            {
                MessageBox.Show("Your current settings will put everything in one place. Aborting.");
                return;
            }
            if (RC != ItemsCount)
            {
                string Effect = (RC < ItemsCount) ? (ItemsCount - RC).ToString() + " items left in place" : (RC - ItemsCount).ToString() + " missing tiles";
                DialogResult dr = MessageBox.Show(string.Format("The input you have placed for Rows and Columns requires {0} items. Currently you have {1}. Using this will have {2}.{3}Continue?",
                    RC.ToString(), ItemsCount.ToString(), Effect, Environment.NewLine), "Item count mismatch", MessageBoxButtons.YesNo);
                if (dr == DialogResult.No) return;
            }

            Placement.HouseItem[] Items = SelectedGridToItems();
            Items = Placement.Tile(Items, v3, Spacing, Rows, Columns, Scaling, chkIgnoreScaling.Checked, chkZeroRotation.Checked);
            layout.ItemstoDB(Items);
        }

        private void NumberText_Leave(object sender, EventArgs e)
        {
            TextBox Sender = (TextBox)sender;
            decimal throwaway;
            if (!decimal.TryParse(Sender.Text, out throwaway)){
                MessageBox.Show("This field needs to be numerical. Please enter a valid value");
                Sender.Focus();
            }
        }

        private void btnDeleteCrate_Click(object sender, EventArgs e)
        {
            foreach (DataGridViewRow rows in dg.Rows)
            {
                try
                {
                    if (bool.Parse(rows.Cells["InCrate"].Value.ToString())) dg.Rows.Remove(rows);
                }
                catch
                {
                    // New Row, Ignore
                }
            }
        }

        private void btnManifest_Click(object sender, EventArgs e)
        {
            string OutFile = "Item Name";
            foreach (DataRow row in layout.HouseItems.Rows)
            {
                OutFile += Environment.NewLine + row["ItemName"].ToString();
            }

            string OutPath = layout.FileName + "_manifest.csv";
            string ConnStr = string.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties=\"text;HDR=Yes;FMT=Delimited\";", Path.GetDirectoryName(OutPath));
            File.WriteAllText(OutPath, OutFile);
            OleDbConnection conn = new OleDbConnection(ConnStr);
            OleDbCommand comm = new OleDbCommand("Select [Item Name], Count(*) AS Item_Count FROM [" + Path.GetFileName(OutPath) + "] GROUP BY [Item Name] ORDER BY [Item Name]", conn);
            conn.Open();

            OleDbDataReader rdr = comm.ExecuteReader();
            OutFile = "\"Item Name\",\"Item Count\"";
            while (rdr.Read())
            {
                OutFile += string.Format(Environment.NewLine + "\"{0}\",\"{1}\"", rdr[0].ToString(), rdr[1].ToString());
            }
            rdr.Close();
            conn.Close();
            File.WriteAllText(OutPath, OutFile);
            if (MessageBox.Show("Manifest file created as" + Environment.NewLine + OutPath + Environment.NewLine + Environment.NewLine + "Open Now?", "File Created", MessageBoxButtons.YesNo) == DialogResult.Yes)
            {
                System.Diagnostics.Process.Start(OutPath);
            }
        }

        private void btnClone_Click(object sender, EventArgs e)
        {
            foreach (DataGridViewRow row in dg.SelectedRows)
            {
                DataRow DR = layout.HouseItems.NewRow();
                DR["DatabaseID"] = -1;
                DR["InCrate"] = bool.Parse(row.Cells["InCrate"].Value.ToString());
                DR["ItemID"] = Int64.Parse(row.Cells["ItemID"].Value.ToString());
                DR["ItemName"] = row.Cells["ItemName"].Value.ToString();
                DR["Pitch"] = decimal.Parse(row.Cells["Pitch"].Value.ToString());
                DR["Roll"] = decimal.Parse(row.Cells["Roll"].Value.ToString());
                DR["Rotation"] = decimal.Parse(row.Cells["Rotation"].Value.ToString());
                DR["Scale"] = decimal.Parse(row.Cells["Scale"].Value.ToString());
                DR["x"] = decimal.Parse(row.Cells["x"].Value.ToString());
                DR["y"] = decimal.Parse(row.Cells["y"].Value.ToString());
                DR["z"] = decimal.Parse(row.Cells["z"].Value.ToString());
                layout.HouseItems.Rows.Add(DR);
            }
        }

        private void Form1_Activated(object sender, EventArgs e)
        {
            if (!layout.FileLoaded) return;
            if (File.GetLastWriteTime(layout.FileName) != layout.LastModified)
            {
                layout.LastModified = File.GetLastWriteTime(layout.FileName);
                if (MessageBox.Show("The layout file has been changed since last load. Reload?", "File Changed", MessageBoxButtons.YesNo) == DialogResult.Yes)
                {
                    layout.Refresh();
                }
            }
        }
        
        private void MassMove_Click(object sender, EventArgs e)
        {
            decimal modifier = 1;
            Button Clicked = (Button)sender;
            decimal MoveAmount = decimal.Parse(txtMoveAmount.Text);
            if (Clicked.Name == "btnDown" || Clicked.Name == "btnEast" || Clicked.Name == "btnNorth") modifier = -1;
            foreach (DataGridViewRow row in dg.SelectedRows)
            {
                switch (Clicked.Name)
                {
                    case "btnUp":
                    case "btnDown":
                        row.Cells["z"].Value = decimal.Parse(row.Cells["z"].Value.ToString()) + modifier * MoveAmount;
                        break;
                    case "btnEast":
                    case "btnWest":
                        row.Cells["x"].Value = decimal.Parse(row.Cells["x"].Value.ToString()) + modifier * MoveAmount;
                        break;
                    case "btnNorth":
                    case "btnSouth":
                        row.Cells["y"].Value = decimal.Parse(row.Cells["y"].Value.ToString()) + modifier * MoveAmount;
                        break;
                    case "btnRotate":
                        row.Cells["Rotation"].Value = decimal.Parse(row.Cells["Rotation"].Value.ToString()) + modifier * MoveAmount;
                        break;
                    case "btnPitch":
                        row.Cells["Pitch"].Value = decimal.Parse(row.Cells["Pitch"].Value.ToString()) + modifier * MoveAmount;
                        break;
                    case "btnRoll":
                        row.Cells["Roll"].Value = decimal.Parse(row.Cells["Roll"].Value.ToString()) + modifier * MoveAmount;
                        break;
                    case "btnRotateReset":
                        row.Cells["Rotation"].Value = 0;
                        row.Cells["Pitch"].Value = 0;
                        row.Cells["Roll"].Value = 0;
                        break;
                    case "btnInCrate":
                        row.Cells["InCrate"].Value = chkMassCrate.Checked;
                        break;
                    case "btnScaling":
                        row.Cells["Scale"].Value = decimal.Parse(txtMassScaling.Text);
                        break;
                    default:
                        // Do nothing or show a message box.
                        MessageBox.Show(Clicked.Name);
                        break;
                }
            }
        }
    }
}
